﻿using Common.Framework.Core.Cache;
using Common.Framework.Core.Common;
using Common.Framework.Core.Const;
using Common.Framework.Core.Extension;
using Microsoft.AspNetCore.Http;
using MongoDB.Bson;
using MongoDB.Driver;
using Snowflake.Core;
using System.Collections;
using System.Linq.Expressions;
using System.Reflection;

namespace Common.Framework.Core.MongoDB
{
    /// <summary>
    /// MongoDB基础操作类
    /// </summary>
    /// <typeparam name="TDoc"></typeparam>
    public class MongoBaseRepository<TDoc> : IMongoBaseRepository<TDoc> where TDoc : BaseMongoEntity, new()
    {
        /// <summary>
        /// 雪花id
        /// </summary>
        private readonly IdWorker idWorker;

        /// <summary>
        /// 
        /// </summary>
        private readonly MongoFactory dbConnectionFactory;

        /// <summary>
        /// 表名
        /// </summary>
        protected string TableName => typeof(TDoc).Name;

        /// <summary>
        /// 当前对象访问数据库时需要用到的数据库链接字符串
        /// </summary>
        private string ConnectionStringName
        {
            get
            {
                string cacheKey = $"reflect_conn:{TableName}";
                string connName = MemoryCache.Instance.Get<string>(cacheKey);
                if (string.IsNullOrWhiteSpace(connName))
                {
                    var tmpConnectionNameAttribute = typeof(TDoc).GetCustomAttributes().FirstOrDefault(s => s.TypeId.ToString() == "Common.Framework.Core.Common.ConnectionNameAttribute");
                    if (tmpConnectionNameAttribute != null)
                    {
                        connName = (tmpConnectionNameAttribute as ConnectionNameAttribute).ConnectionStringName;
                    }
                    else
                    {
                        //如果没有找到分库链接特性,则赋值默认值
                        connName = "DefaultConnectionString";
                    }
                    MemoryCache.Instance.SetSliding(cacheKey, connName, 86400);
                }
                return connName;
            }
        }

        /// <summary>
        /// 获取DB
        /// </summary>        
        /// <returns></returns>
        public IMongoDatabase Connection()
        {
            return this.dbConnectionFactory.GetDatabase(ConnectionStringName);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="idWorker"></param>
        /// <param name="dbConnectionFactory"></param>
        public MongoBaseRepository(IdWorker idWorker, MongoFactory dbConnectionFactory)
        {
            this.idWorker = idWorker;
            this.dbConnectionFactory = dbConnectionFactory;
        }

        /// <summary>
        /// 生成唯一id
        /// </summary>
        /// <returns></returns>
        public long GenerateId()
        {
            return this.idWorker.NextId();
        }

        #region 增

        /// <summary>
        /// 新增文档
        /// 案例：InsertAsync(new SysLogInfo { LogDT = DateTime.Now, Level = "Info", Msg = "测试消息" })
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="options">新增设置</param>        
        public async Task<long> InsertAsync(TDoc doc, InsertOneOptions options = null)
        {
            return await InsertAsync(TableName, doc, options);
        }

        /// <summary>
        /// 插入自定义数据
        /// </summary>
        /// <param name="bson"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public async Task<long> InsertAsync(BsonDocument bson, InsertOneOptions options = null)
        {
            long id;
            if (!bson.Contains("Id"))
            {
                id = GenerateId();
                bson["Id"] = id;
            }
            else
            {
                id = bson["Id"].ToInt64();
            }

            bson["DeleteFlag"] = 0;
            bson["CreateTime"] = DateTime.UtcNow;
            bson["UpdateTime"] = DateTime.UtcNow;
            var colleciton = Connection().GetCollection<BsonDocument>(TableName);
            await colleciton.InsertOneAsync(bson, options);
            return id;
        }

        /// <summary>
        /// 新增文档
        /// 案例：InsertAsync("SysLog1", new SysLogInfo { LogDT = DateTime.Now, Level = "Info", Msg = "测试消息" })
        /// </summary>
        /// <param name="collectionName">文档名</param>        
        /// <param name="doc">文档</param>
        /// <param name="options">新增设置</param>
        private async Task<long> InsertAsync(string collectionName, TDoc doc, InsertOneOptions options = null)
        {
            if (doc.Id <= 0)
            {
                doc.Id = GenerateId();
            }
            var colleciton = GetCollection(collectionName, null);
            doc.DeleteFlag = 0;
            doc.CreateTime = DateTime.UtcNow;
            doc.UpdateTime = DateTime.UtcNow;
            doc.__v++;
            await colleciton.InsertOneAsync(doc, options);
            return doc.Id;
        }

        /// <summary>
        /// 新增文档
        /// 案例：BatchInsertAsync(new List<SysLogInfo>{ new SysLogInfo { LogDT = DateTime.Now, Level = "Info", Msg = "测试消息" }})
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="options">新增设置</param>
        public async Task<List<long>> BatchInsertAsync(IEnumerable<TDoc> docs, InsertManyOptions options = null)
        {
            return await BatchInsertAsync(TableName, docs, options);
        }

        /// <summary>
        /// 批量新增
        /// 案例：BatchInsertAsync("SysLog1", new List<SysLogInfo>{ new SysLogInfo { LogDT = DateTime.Now, Level = "Info", Msg = "测试消息" }})
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="docs">文档集合</param>
        /// <param name="options">新增设置</param
        private async Task<List<long>> BatchInsertAsync(string collectionName, IEnumerable<TDoc> docs, InsertManyOptions options = null)
        {
            var list = docs.ToList();
            list.ForEach(x =>
            {
                if (x.Id <= 0)
                {
                    x.Id = GenerateId();
                }
            });
            var colleciton = GetCollection(collectionName, null);
            await colleciton.InsertManyAsync(list, options);
            return list.Select(en => en.Id).ToList();
        }

        #endregion

        #region 改

        /// <summary>
        /// 修改文档
        /// 案例：UpdateAsync(new SysLogInfo { _id = ObjectId("5c7c94f7b738612163d96bee"), LogDT = DateTime.Now, Level = "Error", Msg = "测试消息2" }, t => t.LogDT==new DateTime(1900,1,1))
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="filter">查询条件,默认使用_id进行更新</param>
        /// <param name="options">修改设置</param>        
        public async Task<long> UpdateAsync(TDoc doc, Expression<Func<TDoc, bool>> filter = null, UpdateOptions options = null)
        {
            var colleciton = GetCollection(TableName, null);

            doc.UpdateTime = DateTime.UtcNow;
            doc.__v++;

            if (filter == null)
            {
                filter = s => s._id == doc._id;//默认使用_id进行更新
            }

            List<UpdateDefinition<TDoc>> updateList = BuildUpdateDefinition(doc, null);
            UpdateResult result = await colleciton.UpdateOneAsync(filter, Builders<TDoc>.Update.Combine(updateList), options);
            var flag = result.IsAcknowledged;
            if (flag)
            {
                flag = result.ModifiedCount > 0;
            }
            return flag ? doc.Id : 0;
        }

        /// <summary>
        /// 修改文档
        /// 案例：UpdateAsync(model, t => t.Level == "Info");
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="filter">查询条件,默认使用_id进行条件查询</param>
        /// <param name="updateFields">修改字段</param>
        /// <param name="options">修改设置</param>
        public async Task<long> UpdateAsync(TDoc doc, UpdateDefinition<TDoc> updateFields, Expression<Func<TDoc, bool>> filter = null, UpdateOptions options = null)
        {
            if (filter == null)
            {
                filter = s => s._id == doc._id;//默认使用_id进行更新
            }
            return await UpdateAsync(TableName, doc, filter, updateFields, options);
        }

        /// <summary>
        /// 修改文档
        /// 案例：UpdateAsync("SysLog1", model, t => t.Level == "Info");
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="doc">文档</param>
        /// <param name="filter">查询条件,默认使用_id进行条件查询</param>
        /// <param name="updateFields">修改字段</param>
        /// <param name="options">修改设置</param>
        private async Task<long> UpdateAsync(string collectionName, TDoc doc, Expression<Func<TDoc, bool>> filter, UpdateDefinition<TDoc> updateFields, UpdateOptions options = null)
        {
            var colleciton = GetCollection(collectionName, null);

            doc.UpdateTime = DateTime.UtcNow;

            doc.__v++;

            if (filter == null)
            {
                filter = s => s._id == doc._id;//默认使用_id进行更新
            }

            UpdateResult result = await colleciton.UpdateOneAsync(filter, updateFields, options);
            var flag = result.IsAcknowledged;
            if (flag)
            {
                flag = result.ModifiedCount > 0;
            }
            return flag ? doc.Id : 0;
        }

        /// <summary>
        /// 生成更新脚本
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        private List<UpdateDefinition<TDoc>> BuildUpdateDefinition(object doc, string parent)
        {
            var updateList = new List<UpdateDefinition<TDoc>>();
            foreach (var property in doc.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                var key = parent == null ? property.Name : $"{parent}.{property.Name}";
                //非空的复杂类型
                if ((property.PropertyType.IsClass || property.PropertyType.IsInterface) && property.PropertyType != typeof(string) && property.GetValue(doc) != null)
                {
                    var subObj = property.GetValue(doc);
                    if (typeof(IList).IsAssignableFrom(property.PropertyType))
                    {
                        #region 集合类型
                        int i = 0;
                        foreach (var item in subObj as IList)
                        {
                            var itemType = item.GetType();
                            if ((itemType.IsClass && itemType.Name != "String") || itemType.IsInterface)
                            {
                                updateList.AddRange(BuildUpdateDefinition(item, $"{key}.{i}"));
                            }
                            else
                            {
                                updateList.Add(Builders<TDoc>.Update.Set(string.Format("{0}.{1}", key, i), item));
                            }
                            i++;
                        }
                        #endregion
                    }
                    else if (typeof(BsonDocument).IsAssignableFrom(property.PropertyType))
                    {
                        updateList.Add(Builders<TDoc>.Update.Set(key, subObj));
                    }
                    else
                    {
                        #region 实体类型
                        //复杂类型，导航属性，类文档和集合文档 
                        foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                        {
                            updateList.Add(Builders<TDoc>.Update.Set(string.Format("{0}.{1}", key, sub.Name), sub.GetValue(subObj)));
                        }
                        #endregion
                    }
                }
                else //简单类型
                {
                    updateList.Add(Builders<TDoc>.Update.Set(key, property.GetValue(doc)));
                }
            }

            return updateList;
        }

        #endregion

        #region 删

        public async Task<UpdateResult> SoftDeleteAsync(string _id, Expression<Func<TDoc, bool>> filter = null)
        {
            var update = Builders<TDoc>.Update
                .Set(s => s.UpdateTime, DateTime.UtcNow)
                .Set(s => s.DeleteFlag, CommonConst.DeleteFlagDelete);

            if (filter == null)
            {
                filter = s => s._id == _id; //默认根据_id进行删除
            }
            
            UpdateResult result = await GetCollection(TableName, null).UpdateOneAsync<TDoc>(filter, update);

            return result;
        }

        /// <summary>
        /// 物理删除文档
        /// 案例：RealDeleteAsync(t => t.Level == "Info");
        /// </summary>
        /// <param name="filter">查询条件</param>
        /// <param name="options">删除设置</param>
        public async Task<DeleteResult> RealDeleteAsync(Expression<Func<TDoc, bool>> filter, DeleteOptions options = null)
        {
            return await RealDeleteAsync(TableName, filter, options);
        }

        /// <summary>
        /// 物理删除文档
        /// 案例：RealDeleteAsync("SysLog1", t => t.Level == "Info");
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="filter">查询条件</param>
        /// <param name="options">删除设置</param>
        private async Task<DeleteResult> RealDeleteAsync(string collectionName, Expression<Func<TDoc, bool>> filter, DeleteOptions options = null)
        {
            var colleciton = GetCollection(collectionName, null);
            return await colleciton.DeleteOneAsync(filter, options);
        }

        /// <summary>
        /// 物理批量删除
        /// 案例：RealBatchDeleteAsync(t => t.Level == "Info");
        /// </summary>
        /// <param name="filter">查询条件</param>
        /// <param name="options">删除设置</param>
        public async Task<DeleteResult> RealBatchDeleteAsync(Expression<Func<TDoc, bool>> filter, DeleteOptions options = null)
        {
            return await RealBatchDeleteAsync(TableName, filter, options);
        }

        /// <summary>
        /// 物理批量删除
        /// 案例：RealBatchDeleteAsync("SysLog1", t => t.Level == "Info");
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="filter">查询条件</param>
        /// <param name="options">删除设置</param>
        private async Task<DeleteResult> RealBatchDeleteAsync(string collectionName, Expression<Func<TDoc, bool>> filter, DeleteOptions options = null)
        {
            var colleciton = GetCollection(collectionName, null);
            return await colleciton.DeleteManyAsync(filter, options);
        }

        #endregion

        #region 查

        /// <summary>
        /// 查询单条记录
        /// 案例：QueryAsync(t => t.Level == "Info")
        /// </summary>
        /// <param name="filter">查询条件</param>
        /// <param name="options">查询设置</param>
        /// <returns></returns>
        public async Task<TDoc> QueryAsync(Expression<Func<TDoc, bool>> filter, FindOptions options = null)
        {
            return await QueryAsync(TableName, filter, options);
        }

        /// <summary>
        /// 查询单条记录
        /// 案例：QueryAsync("SysLog1", t => t.Level == "Info")
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="filter">查询条件</param>
        /// <param name="options">查询设置</param>
        /// <returns></returns>
        private async Task<TDoc> QueryAsync(string collectionName, Expression<Func<TDoc, bool>> filter, FindOptions options = null)
        {
            var collection = GetCollection(collectionName, null);
            var result = await collection.Find<TDoc>(filter, options).FirstOrDefaultAsync();
            return result;
        }

        /// <summary>
        /// 查询多条记录 Builders<TDoc>.Filter.Eq("", "") & Builders<TDoc>.Filter.Eq("", "") | Builders<TDoc>.Filter.Eq("", "");
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="options"></param> 
        /// <returns></returns>
        public async Task<List<TDoc>> QueryListAsync(Expression<Func<TDoc, bool>> filter, FindOptions options = null)
        {
            return await QueryListAsync(TableName, filter, options);
        }

        /// <summary>
        /// 查询多条记录 Builders<TDoc>.Filter.Eq("", "") & Builders<TDoc>.Filter.Eq("", "") | Builders<TDoc>.Filter.Eq("", "");
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="options"></param> 
        /// <returns></returns>
        private async Task<List<TDoc>> QueryListAsync(string collectionName, Expression<Func<TDoc, bool>> filter, FindOptions options = null, Expression<Func<TDoc, object>> orderByKey = null)
        {
            var collection = GetCollection(collectionName, null);
            if (orderByKey == null) orderByKey = en => en.Id;
            var result = await collection.Find<TDoc>(filter, options).SortByDescending(orderByKey).ToListAsync();
            return result;
        }

        /// <summary>
        /// 分页获得集合
        /// 案例：QueryPageListAsync(t=>t.Level=="Info", t=>t, 1, 20, out rsCount)
        /// </summary>
        /// <param name="filter">查询条件</param>
        /// <param name="orderByKey">排序</param>
        /// <param name="pageIndex">页面索引</param>
        /// <param name="pageSize">每页显示数</param>
        /// <returns></returns>
        public async Task<BasePageResponse<TDoc>> QueryPageListAsync(Expression<Func<TDoc, bool>> filter, Expression<Func<TDoc, object>> orderByKey = null, int pageIndex = 1, int pageSize = 10)
        {
          
            return await QueryPageListAsync(TableName, filter, orderByKey, pageIndex, pageSize);
        }

        /// <summary>
        /// 分页获得集合
        /// 案例：QueryPageListAsync<SysLogInfo>("SysLog1", t=>t.Level=="Info", t=>t, 1, 20, out rsCount)
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="filter">查询条件</param>
        /// <param name="orderByKey">排序</param>
        /// <param name="pageIndex">页面索引</param>
        /// <param name="pageSize">每页显示数</param>
        /// <returns></returns>
        private async Task<BasePageResponse<TDoc>> QueryPageListAsync(string collectionName, Expression<Func<TDoc, bool>> filter, Expression<Func<TDoc, object>> orderByKey = null, int pageIndex = 1, int pageSize = 10)
        {

            BasePageResponse<TDoc> page = new BasePageResponse<TDoc>();
            var currentDb = Connection();
            var colleciton = GetCollection(currentDb, collectionName, null);
            var existsBool = await CollectionExistsAsync(currentDb, collectionName);
            if (!existsBool)
            {
                return new BasePageResponse<TDoc>();
            }
            long totalCount = await colleciton.CountDocumentsAsync(filter);

            long pageCount = totalCount / pageSize + ((totalCount % pageSize) > 0 ? 1 : 0);
            if (pageIndex > pageCount) pageIndex = (int)pageCount; //因为记录数理论上不会超过int类型的范围,所以这里进行强制转换不会丢失精度
            if (pageIndex <= 0) pageIndex = 1;
            if (orderByKey == null) orderByKey = en => en.Id;

            var pageResult = await colleciton.Find(filter)
                .SortByDescending(orderByKey)                
                .Skip((pageIndex - 1) * pageSize)                
                .Limit(pageSize)
                .ToListAsync();
            page.DataList = pageResult;

            page.Total = (int)totalCount;//因为记录数理论上不会超过int类型的范围,所以这里进行强制转换不会丢失精度
            return page;
        }

        /// <summary>
        /// 查询集合-返回指定的记录数
        /// </summary>
        /// <param name="filter">查询条件</param>
        /// <param name="LimitCount">需要返回的记录数</param>
        /// <returns></returns>
        public async Task<List<TDoc>> QueryTopList(Expression<Func<TDoc, bool>> filter, int limitCount)
        {
            var collection = GetCollection(TableName, null);
            var result = await collection.Find(filter).ToListAsync();
            var takeResult = result.Take(limitCount).ToList();
            return takeResult;
        }

        /// <summary>
        /// Count
        /// </summary>
        /// <param name="filter">查询条件</param>
        /// <param name="keySelector">排序</param>
        /// <param name="query">查询类</param>
        /// <returns></returns>
        public async Task<long> CountAsync(Expression<Func<TDoc, bool>> filter)
        {
            var colleciton = GetCollection(TableName, null);
            return await colleciton.CountDocumentsAsync(filter);
        }

        /// <summary>
        /// 返回单个字段集合（去重）
        /// </summary>
        /// <typeparam name="TResult">字段类型</typeparam>
        /// <param name="filter">条件</param>
        /// <param name="distinctField">去重字段</param>
        /// <returns></returns>
        public async Task<List<TResult>> DistinctAsync<TResult>(Expression<Func<TDoc, bool>> filter = null, string distinctField = "")
        {
            if (filter == null)
            {
                filter = en => en.DeleteFlag == CommonConst.DeleteFlagUnDelete;
            }
            var colleciton = GetCollection(TableName, null);
            FieldDefinition<TDoc, TResult> field = distinctField;
            var list = await colleciton.DistinctAsync(field, filter);
            return await list.ToListAsync();
        }
        #endregion

        #region 其它操作
        /// <summary>
        /// 创建文档
        /// </summary>
        /// <param name="indexFields">字段名</param>
        /// <param name="options">索引设置</param>
        public async Task CreateCollectionAsync(string[] indexFields = null, CreateIndexOptions options = null)
        {
            await CreateCollectionAsync(TableName, indexFields, options);
        }
        /// <summary>
        /// 验证集合文档(表)是否存在
        /// </summary>
        /// <param name="database"></param>
        /// <param name="collectionName"></param>
        /// <returns></returns>
        private async Task<bool> CollectionExistsAsync(IMongoDatabase database, string collectionName)
        {
            var options = new ListCollectionsOptions
            {
                Filter = Builders<BsonDocument>.Filter.Eq("name", collectionName)
            };
            var result = await database.ListCollectionsAsync(options);

            return result.ToEnumerable().Any();
        }

        /// <summary>
        /// 获取集合文档文档
        /// </summary>
        /// <typeparam name="TDoc">类型</typeparam>        
        /// <param name="name">类型名</param>
        /// <param name="settings">集合文档配置</param>
        /// <returns></returns>
        public IMongoCollection<TDoc> GetCollection(string name, MongoCollectionSettings settings = null)
        {
            return GetCollection(Connection(), name, settings);
        }

        /// <summary>
        /// 获取集合文档文档
        /// </summary>
        /// <typeparam name="TDoc">类型</typeparam>
        /// <param name="database">database</param>
        /// <param name="name">类型名</param>
        /// <param name="settings">集合文档配置</param>
        /// <returns></returns>
        private IMongoCollection<TDoc> GetCollection(IMongoDatabase database, string name, MongoCollectionSettings settings = null)
        {
            return database.GetCollection<TDoc>(name, settings);
        }
        #endregion

        #region 创建索引

        /// <summary>
        /// 清空重置文档集合
        /// 案例：ClearCollection("SysLog1");
        /// </summary>
        /// <param name="collectionName">文档名</param>
        public async Task ClearCollectionAsync(string collectionName)
        {
            var currentDb = Connection();
            var colleciton = GetCollection(currentDb, collectionName, null);
            var indexs = await colleciton.Indexes.ListAsync();
            List<IEnumerable<BsonDocument>> docIndexs = new List<IEnumerable<BsonDocument>>();
            while (indexs.MoveNext())
            {
                docIndexs.Add(indexs.Current);
            }
            await currentDb.DropCollectionAsync(collectionName);

            var existsBool = await CollectionExistsAsync(currentDb, collectionName);
            if (!existsBool)
            {
                await CreateCollectionAsync(currentDb, collectionName);
            }
        }

        /// <summary>
        /// 创建索引(倒序)
        /// </summary>
        /// <typeparam name="TDoc">数据表基础类</typeparam>
        /// <param name="col">文档集合</param>
        /// <param name="indexFields">索引字段</param>
        /// <param name="options">索引设置</param>
        private async Task CreateDescIndexAsync(IMongoCollection<TDoc> col, string[] indexFields, CreateIndexOptions options = null)
        {
            if (indexFields == null)
            {
                return;
            }
            var indexKeys = Builders<TDoc>.IndexKeys;
            IndexKeysDefinition<TDoc> keys = null;
            if (indexFields.Length > 0)
            {
                keys = indexKeys.Descending(indexFields[0]);
            }
            for (var i = 1; i < indexFields.Length; i++)
            {
                var strIndex = indexFields[i];
                keys = keys.Descending(strIndex);
            }

            if (keys != null)
            {
                await col.Indexes.CreateOneAsync(new CreateIndexModel<TDoc>(keys, options));
            }
        }

        /// <summary>
        /// 创建索引(正序)
        /// </summary>
        /// <typeparam name="TDoc">数据表基础类</typeparam>
        /// <param name="col">文档集合</param>
        /// <param name="indexFields">索引字段</param>
        /// <param name="options">索引设置</param>
        private async Task CreateAscIndexAsync(IMongoCollection<TDoc> col, string[] indexFields, CreateIndexOptions options = null)
        {
            if (indexFields == null)
            {
                return;
            }
            var indexKeys = Builders<TDoc>.IndexKeys;
            IndexKeysDefinition<TDoc> keys = null;
            if (indexFields.Length > 0)
            {
                keys = indexKeys.Ascending(indexFields[0]);
            }
            for (var i = 1; i < indexFields.Length; i++)
            {
                var strIndex = indexFields[i];
                keys = keys.Ascending(strIndex);
            }

            if (keys != null)
            {
                await col.Indexes.CreateOneAsync(new CreateIndexModel<TDoc>(keys, options));
            }
        }

        /// <summary>
        /// 创建文档
        /// 案例：CreateCollection("SysLog1", new[]{"LogDT"});
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="indexFields">索引字段</param>
        /// <param name="options">索引设置</param>
        private async Task CreateCollectionAsync(IMongoDatabase database, string collectionName, string[] indexFields = null, CreateIndexOptions options = null)
        {
            await database.CreateCollectionAsync(collectionName);
            await CreateDescIndexAsync(GetCollection(database, collectionName, null), indexFields, options);
        }

        /// <summary>
        /// 创建文档
        /// 案例：CreateCollection("SysLog1", new[]{"LogDT"});
        /// </summary>
        /// <param name="collectionName">文档名</param>
        /// <param name="indexFields">索引字段</param>
        /// <param name="options">索引设置</param>
        private async Task CreateCollectionAsync(string collectionName, string[] indexFields = null, CreateIndexOptions options = null)
        {
            await CreateCollectionAsync(Connection(), collectionName, indexFields, options);
        }
        #endregion
    }
}
